/**
 * 
 */
package com.sanid.wqb;

import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.wave.api.Blip;
import com.google.wave.api.Event;
import com.google.wave.api.EventType;
import com.google.wave.api.RobotMessageBundle;
import com.google.wave.api.TextView;
import com.google.wave.api.Wavelet;

/**
 * @author schroetelm
 *
 */
public class Channel {
	
	public enum State {
		IDLE, ASKING
	}
	
	private static final Logger logger = Logger.getLogger("waveqbot");
	
	private static final String BOT_NAME = "waveqbot@appspot.com";
	private static final String LINKY_NAME = "linky@gwave.com";
	
	private static final Pattern PATTERN_LAST_COMMAND = Pattern.compile("(^|\\n)/([\\w\\d ]+?)\\r?\\n\\r?\\n$");
	private static final Pattern PATTERN_LAST_LINE = Pattern.compile("(^|\\n)(.+?)\\r?\\n\\r?\\n$");
	
	private static int channels = 0;
	
	private String waveId;
	private String waveletId;
	private String blipId;
	private boolean useRootBlip = true;
	private State state = State.IDLE;
	private int currentQuestion = 0;
	
	/**
	 * 
	 */
	public Channel(RobotMessageBundle bundle) {
		channels++;
		
		// Wavelet of this channel
		Wavelet wavelet = bundle.getWavelet();
		// Store wave id
		waveId = wavelet.getWaveId();
		// Store wavelet id
		waveletId = wavelet.getWaveletId();
		
		
		// Create blip for output
		Blip myBlip = wavelet.appendBlip();
		blipId = myBlip.getBlipId();
		
		appendMsgLn(bundle, "Hello I am your friendly quiz-robot.");
		appendMsgLn(bundle, "I am active in '"+channels+"' channel(s).");
	}

	/**
	 * @param bundle
	 */
	public void processEvents(RobotMessageBundle bundle) {
		Blip out = getOutputBlip(bundle);
		String outId = out.getBlipId();
		
		if (bundle.wasSelfAdded()) {
			logger.info("Joined channel");
			//appendMsgLn(bundle, "Event: SelfAdded");
		}
	
		for (Event e : bundle.getEvents()) {
			if (e.getType() == EventType.WAVELET_PARTICIPANTS_CHANGED) {
				logger.info("Someone else added: " + e.getAddedParticipants().iterator().next());
				for (String string : e.getAddedParticipants()) {
					appendMsgLn(bundle, "Welcome "+string);
				}
			} else if(e.getType() == EventType.BLIP_SUBMITTED) {
				logger.info("Blip submitted");
				if(e.getBlip() != null && !e.getBlip().getBlipId().equalsIgnoreCase(outId)) {
					// Modified blip is not the robot-output blib
					//appendMsgLn(bundle, "Event: BLIP_SUBMITTED");
				}
			} else if(e.getType() == EventType.BLIP_VERSION_CHANGED) {
				logger.info("Blip version changed");
				if(!e.getBlip().getBlipId().equalsIgnoreCase(outId)) {
					// Modified blip is not the robot-output blib
					if(state.equals(State.ASKING)) {
						TextView text = e.getBlip().getDocument();
						String content = text.getText();
						if(isAnswered(bundle, content)) {
							//state = State.IDLE;
							currentQuestion++;
							appendMsgLn(bundle, "Correct answer from " + e.getModifiedBy()+"!\n");
							ask(bundle);
						}
					} else {
						// User-blib changed but no question going on
						//appendMsgLn(bundle, "Event: Changed user blib (not asking)");
					}
				} else {
					// Change of root blip
					if(BOT_NAME.equalsIgnoreCase(e.getModifiedBy())) {
						// Modified by bot himself
					} else if(LINKY_NAME.equalsIgnoreCase(e.getModifiedBy())) {
						// Modified by whatsoever google voodoo bot
					} else {
						// User wrote to bot-blip
						TextView text = out.getDocument();
						String content = text.getText();
						Matcher matcher = PATTERN_LAST_COMMAND.matcher(content);
						if(matcher.find()) {
							String command = matcher.group(2);
							if(command.trim().equalsIgnoreCase("ask")) {
								state = State.ASKING;
								ask(bundle);
							}
						}
					}
				}
			}
		}
	}
	
	protected void ask(RobotMessageBundle bundle) {
		Question question = QuestionRepository.getInstance().getQuestions().get(currentQuestion);
		appendMsgLn(bundle, "Question from the category \""+question.getCategory()+"\"");
		appendMsgLn(bundle, "<i>"+question.getQuestion()+"</i> - "+question.getAnswer());
	}
	
	protected boolean isAnswered(RobotMessageBundle bundle, String text) {
		Question question = QuestionRepository.getInstance().getQuestions().get(currentQuestion);
		Matcher matcher = PATTERN_LAST_LINE.matcher(text);
		if(matcher.find()) {
			String line = matcher.group(2);
			line = line.trim();
			//appendMsgLn(bundle, "Event: Changed user blib ("+line+")");
			if(line.equalsIgnoreCase(question.getAnswer())) {
				// Main answer given
				return true;
			} else {
				// Check for alternate answers
				for (String alternateAnswer : question.getAlternateAnswers()) {
					if(line.equalsIgnoreCase(alternateAnswer)) {
						return true;
					}
				}
			}
		}
		return false;
	}
	
	public void appendMsgLn(RobotMessageBundle bundle, String message) {
		Blip blip = getOutputBlip(bundle);
		if(blip.isDocumentAvailable()) {
			TextView textView = blip.getDocument();
			textView.append(message+"\n");
		} else {
			logger.warning("Unable to write message: " + message);
		}
	}
	
	public Blip getOutputBlip(RobotMessageBundle bundle) {
		Wavelet wt = bundle.getWavelet();
		if(useRootBlip) {
//			return bundle.getWavelet().getRootBlip();
			return bundle.getBlip(wt.getWaveId(), wt.getWaveletId(), wt.getRootBlipId());
		} else {
			return bundle.getBlip(waveId, waveletId, blipId);
		}
	}
}
